import type { PageType } from '../../../lib/page_handler/type'
import type { GreasyForkElements } from '../../../types/constants/personalization/greasy_fork'
import type { ComponentStyleIdType, PlatformTypeValue } from '../../../types/interfaces'
import { BaseModule } from '../../../lib/abstract'
import { PageHandler } from '../../../lib/page_handler'
import { GreasyForkPageType } from '../../../lib/page_handler/platform/greasyfork/types'
import {
  ComponentStyleId,
  HOSTNAME,
  logger,
  PAGE_ELEMENTS,
  SUPPORTED_PLATFORMS,
} from '../../../types/constants'
import { ConfigManager } from '../../config_manager'
import { StyleManager } from '../../style_manager'

interface TimeConfig {
  /** 容器选择器 */
  containerSelector: string
  /** 时间元素选择器 */
  timeElementSelector: string
  /** 时间提取函数 */
  extractTime: ($el: JQuery) => string | null
}

type PageTimeConfig = Partial<Record<string, TimeConfig>>
type PlatformTimeConfig = Partial<Record<PlatformTypeValue, PageTimeConfig>>

interface Config {
  enabled?: boolean
}

export class TimeInterval extends BaseModule {
  readonly id: string = 'time_interval'
  readonly styleId: string = ComponentStyleId[this.name]
  isInitialized: boolean = false
  readonly supportedPlatforms: string[] = ConfigManager.getInstance().moduleSupportedPlatforms(this.name)
  private static instance: TimeInterval
  elements: GreasyForkElements = PAGE_ELEMENTS[SUPPORTED_PLATFORMS.GREASY_FORK]
  private currentPageType: PageType | null = null
  private readonly timeConfigs: PlatformTimeConfig = {}
  private currentPageConfig: TimeConfig | null = null

  config: Config = {
    enabled: true,
  }

  get name(): ComponentStyleIdType {
    return 'TimeInterval'
  }

  constructor() {
    super()

    this.timeConfigs = {
      [SUPPORTED_PLATFORMS.GREASY_FORK]: {
        // 测试链接：https://greasyfork.org/zh-CN/scripts/430877/discussions/307697
        [GreasyForkPageType.SCRIPT_DISCUSSION]: {
          containerSelector: '#script-info .comment',
          timeElementSelector: '.comment-meta relative-time',
          extractTime: ($el: JQuery) => $el.attr('datetime') ?? null,
        },
        // 测试链接：https://greasyfork.org/zh-CN/discussions/greasyfork/303215
        [GreasyForkPageType.DISCUSSIONS_DETAIL]: {
          containerSelector: '.text-content .comment',
          timeElementSelector: '.comment-meta relative-time',
          extractTime: ($el: JQuery) => $el.attr('datetime') ?? null,
        },
      },
    }
  }

  /**
   * 获取单例实例
   */
  public static getInstance(): TimeInterval {
    if (!TimeInterval.instance) {
      TimeInterval.instance = new TimeInterval()
    }
    return TimeInterval.instance
  }

  handleCleanupReferences(): void {
    // 1.清除数据
    this.currentPageType = null
  }

  handleCleanupCreatedElements(): void {
    // 1. 移除所有添加的元素
    $(`${this.currentPageConfig?.containerSelector} .time-interval`).remove()
  }

  core(): void {
    this.loadConfig()

    if (!this.config.enabled)
      return

    this.applyTimeInterval()

    // 注册样式
    StyleManager.getInstance().registerStyle(this.styleId, this.getStyles(), false, true)
  }

  onToggleCallback(_id: string, checked: boolean): void {
    super.onToggleCallback(_id, checked)
  }

  private applyTimeInterval(): void {
    this.currentPageType = PageHandler.getCurrentPageType()

    const platformConfig = this.timeConfigs[HOSTNAME]
    if (!platformConfig)
      return

    const config = platformConfig[this.currentPageType] as any
    if (!config)
      return

    this.currentPageConfig = config
    const $containers = $(config.containerSelector)

    // 至少需要两个评论才能计算间隔
    if (!$containers || $containers.length < 2)
      return

    let prevTime: number | null = null

    $containers.each((_index, container) => {
      const $container = $(container)
      const $timeElement = $(container).find(config.timeElementSelector)
      const datetime = config.extractTime($timeElement)

      if (!datetime)
        return

      const currentTime = new Date(datetime).getTime()

      if (currentTime && prevTime !== null) {
        const intervalText = this.formatTimeInterval(prevTime, Number(currentTime))
        const $interval = $(`<div class="time-interval">⏱️ 距上一条评论: ${intervalText}</div>`)
        $container.append($interval)
      }

      prevTime = currentTime ?? prevTime // 保留上一个有效时间
    })
  }

  /**
   * 格式化时间间隔
   */
  private formatTimeInterval(prevTime: number, currentTime: number): string {
    const diffSeconds = Math.floor((currentTime - prevTime) / 1000)

    const years = Math.floor(diffSeconds / (86400 * 365))
    const months = Math.floor((diffSeconds % (86400 * 365)) / (86400 * 30))
    const days = Math.floor((diffSeconds % (86400 * 30)) / 86400)
    const hours = Math.floor((diffSeconds % 86400) / 3600)
    const minutes = Math.round((diffSeconds % 3600) / 60) // 四舍五入（向最近的整数取整）
    const seconds = diffSeconds % 60

    const parts: string[] = []

    // 年级单位
    if (years > 0) {
      parts.push(`${years}年`)
      // 超过1年时只显示年和月
      if (months > 0)
        parts.push(`${months}个月`)
      return parts.join('')
    }

    // 月级单位
    if (months > 0) {
      parts.push(`${months}个月`)
      // 超过1个月时只显示月/天
      if (days > 0)
        parts.push(`${days}天`)
      return parts.join('')
    }

    // 天级单位
    if (days > 0) {
      parts.push(`${days}天`)
      // 超过1天时只显示天/小时
      if (hours > 0)
        parts.push(`${hours}小时`)
      return parts.join('')
    }

    // 小时级单位
    if (hours > 0) {
      parts.push(`${hours}小时`)
      // 超过1小时时只显示小时/分钟
      if (minutes > 0)
        parts.push(`${minutes}分钟`)
      return parts.join('')
    }

    // 分钟级单位
    if (minutes > 0) {
      parts.push(`${minutes}分钟`)
      // 超过1分钟时显示秒（可选）
      if (seconds > 0 && minutes < 5)
        parts.push(`${seconds}秒`)
      return parts.join('')
    }

    // 秒级单位
    if (seconds > 0)
      return `${seconds}秒`

    return '刚刚'
  }

  applyConfig(config: Partial<Config>): void {
    super.updateConfig(config)

    this.applyTimeInterval()

    logger.info(`[${this.name}] Config updated and apply`, this.config)
  }

  getStyles(): string {
    return this.currentPageConfig
      ? `
${this.currentPageConfig.containerSelector}:has(.time-interval) {
  position: relative !important;
  padding-bottom: 2.5em !important;
}

${this.currentPageConfig.containerSelector} {
  .time-interval {
    position: absolute;
    bottom: 0;
    right: 0;
    display: inline-block;
    margin: 0.5em 0;
    padding: 0.2em 2em;
    border-radius: 4px;
    font-size: 0.85em;
    color: #666;
  }
}
`
      : ''
  }
}
